﻿using ComUIControl;
using KCommon;
using KeyboardArg;
using KeyboardFactory;
using KXmlUIControl;
using LogLib;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace KWindow.KPageCore
{
    public partial class PageControlBase
    {

        protected void InitKeyboards()
        {
            Keyboards board = Keyboards.Instance;
            board.KeyboardClosed += OnKeyBoardClosed;
            KeyboardPopup += board.OnKeyboardPopup;
        }

        protected void SetHasInputted(string key)
        {
            if (!HasInputted.ContainsKey(key))
            {
                HasInputted.Add(key, true);
            }
            else
            {
                HasInputted[key] = true;
            }
        }

        protected void textBoxInputting_Enter(object sender, EventArgs e)
        {
            if (!Process.IsRunning)
            {
                return;
            }
            ActivedControl = sender as TextBox;
            SetHasInputted(ActivedControl.Name);
            ShowSoftKeyBoard(ActivedControl);
        }

        protected void textBoxInputting_Click(object sender, EventArgs e)
        {
            if (!Process.IsRunning)
            {
                return;
            }
            ActivedControl = sender as TextBox;
            SetHasInputted(ActivedControl.Name);
            ShowSoftKeyBoard(ActivedControl, true);
        }

        protected void ShowSoftKeyBoard(TextBox tb, bool isClick = false)
        {
            if (TextBoxBindings == null)
            {
                Log.WriteAsync("TextBoxBindings == null");
                return;
            }
            string name = tb.Name;
            if (!TextBoxBindings.ContainsKey(name))
            {
                Log.WriteAsync($"TextBoxBindings.ContainsKey{name}");
                return;
            }
            KeyBoardArgs arg = TextBoxBindings[name];
            arg.LanguageCode = LanguageCode;
            arg.SenderName = name;
            arg.PassageType = KeyboardArg.SendMessageType.Request;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = tb.Text;
            //bool isMainPage = IsMainPage;
            //MessageBox.Show("isMainPage:" + isMainPage.ToString());
            string voiceFileName = XmlControlBase.GetVocieFullPath(arg.VoiceFileName, LanguageCode);

            // 播放语音
            if (File.Exists(voiceFileName))
            {
                Speak(voiceFileName);
            }
            else
            {
                Log.WriteAsync($"语音文件{voiceFileName}不存在.");
            }
            Log.WriteAsync($"用户点击{tb.Name}请求调出键盘:{arg.DictionaryFileName}");
            //string parm = JsonHandler.ConvertToJsonString(arg).Replace('"', '@');
            //SendMessageToKB(this.Handle, parm);
            var screen = Screen.PrimaryScreen;
            if (IsMainPage)
            {
                screen = Screen.AllScreens.Where(t => t.Primary == true).FirstOrDefault();
            }
            else
            {
                screen = Screen.AllScreens.Where(t => t.Primary == false).FirstOrDefault();
            }
            if (null != screen)
                OnKeyboardPopup(arg, screen.WorkingArea);
        }

        protected string[] timeFormats = { "yyyy-MM-dd", "yyyyMMdd" };

        protected IFormatProvider ifp = new CultureInfo("zh-CN", true);

        protected void OnKeyBoardClosed(object sender, KeyboardClosedEventArgs e)
        {
            KeyBoardArgs arg = e.Args;
            if (arg.MsgReceiver != this.Handle)
            {
                return;
            }
            if (!string.IsNullOrEmpty(arg.Command) && arg.Command.Equals("Cancel"))
            {
                Log.WriteAsync("用户取消了输入.");
                return;
            }
            string key = TextBoxBindings.FirstOrDefault(q => q.Value.Key.Equals(arg.Key)).Key;  //get first key
            TextBox tb = TextBoxs.Find(r => r.Name.Equals(key));
            if (tb == null)
            {
                return;
            }
            // 更新字典关键字代码的映射
            if (!string.IsNullOrEmpty(arg.DictionaryFileName))
            {
                textMapService[arg.Key] = arg.Code;
            }
            if (arg.DictionaryFileName.StartsWith("Date"))
            {
                DateTime dt;
                if (DateTime.TryParseExact(
                    arg.Content,
                    timeFormats,
                    ifp,
                    System.Globalization.DateTimeStyles.None,
                    out dt))
                {
                    tb.Text = dt.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.CreateSpecificCulture("zh-CN"));
                }
                else
                {
                    MsgBox.Show($"来自{tb.Name}显示的日期{arg.Content}解析失败!");
                }
            }
            else if (arg.DictionaryFileName.Equals("Citys")
                || arg.DictionaryFileName.Contains("Address"))
            {
                tb.Text = arg.FullContent;
            }
            else
            {
                tb.Text = arg.Content;
                tb.Tag = arg.Tag;
            }
            if (arg.DictionaryFileName.Equals("StandardAddress"))
            {
                Process.SetValue("SignID", arg.Tag);
            }
            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                CheckFillingIsCompleted();
            });
        }

        protected void OnKeyBoardMsgReceived(System.Windows.Forms.Message m)
        {
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            Type mytype = cds.GetType();
            cds = (COPYDATASTRUCT_INTPTR)m.GetLParam(mytype);
            KeyBoardArgs arg = null;
            uint flag = (uint)(cds.dwData);
            byte[] data = new byte[cds.cbData];
            Marshal.Copy(cds.lpData, data, 0, data.Length);
            string jsonString = System.Text.Encoding.UTF8.GetString(data);
            try
            {
                arg = JsonHandler.ConvertToJsonObject<KeyBoardArgs>(jsonString);
            }
            catch (Exception ex)
            {
                string errInfo = string.Format("无法解析的string: \n\t{0}", jsonString);
                MessageBox.Show(errInfo, ex.Message);
                Log.WriteAsync(ex.ToString());
                return;
            }
            if (!string.IsNullOrEmpty(arg.Command) && arg.Command.Equals("Cancel"))
            {
                Log.WriteAsync("用户取消了输入.");
                return;
            }
            string key = TextBoxBindings.FirstOrDefault(q => q.Value.Key.Equals(arg.Key)).Key;  //get first key
            TextBox tb = TextBoxs.Find(r => r.Name.Equals(key));
            if (tb == null)
            {
                return;
            }

            // 更新字典关键字代码的映射
            if (!string.IsNullOrEmpty(arg.DictionaryFileName))
            {
                textMapService[arg.Key] = arg.Code;
            }
            if (arg.DictionaryFileName.StartsWith("Date"))
            {
                DateTime dt;
                if (DateTime.TryParseExact(
                    arg.Content,
                    timeFormats,
                    ifp,
                    System.Globalization.DateTimeStyles.None,
                    out dt))
                {
                    tb.Text = dt.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.CreateSpecificCulture("zh-CN"));
                }
                else
                {
                    MsgBox.Show($"来自{tb.Name}显示的日期{arg.Content}解析失败!");
                }
            }
            else if (arg.DictionaryFileName.Equals("Citys") || arg.DictionaryFileName.Contains("Address"))
            {
                tb.Text = arg.FullContent;
            }
            else
            {
                tb.Text = arg.Content;
                tb.Tag = arg.Tag;
            }
            if (arg.DictionaryFileName.Equals("StandardAddress"))
            {
                Process.SetValue("SignID", arg.Tag);
            }
            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                CheckFillingIsCompleted();
            });
        }

        protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case (int)MessageType.WM_COPYDATA:
                    OnKeyBoardMsgReceived(m);
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }

        protected void CheckFillingIsCompleted()
        {
            if (this.InvokeRequired)
            {
                Action outdelegate = new Action(CheckFillingIsCompleted);
                this.Invoke(outdelegate, new object[] { });
                return;
            }
            foreach (TextBox tb in TextBoxs)
            {
                if (!tb.Enabled)
                {
                    continue;
                }
                if (!TextBoxBindings.ContainsKey(tb.Name))
                {
                    continue;
                }
                if (!string.IsNullOrEmpty(tb.Text))
                {
                    Log.WriteAsync($"{tb.Name}不为空,跳过输入.");
                    continue;
                }
                Log.WriteAsync($"{tb.Name}为空【{tb.Text}】,准备输入.");
                KeyBoardArgs args = TextBoxBindings[tb.Name];
                if (args.NotNull)
                {
                    tb.Focus();
                    return;
                }
                else
                {
                    continue;
                }
            }
        }
    }
}
